﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Text.RegularExpressions;
using VideoRentalShop.Controller;
using VideoRentalShop.Model;

namespace VideoRentalShop.View.Windows.ClientList
{
    /// <summary>
    /// Logika interakcji dla klasy EditPanel.xaml
    /// </summary>
    public partial class EditPanel : UserControl
    {
        private readonly static Regex EMAIL_REGEX = new Regex(@"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        private readonly static Regex PESEL_REGEX = new Regex(@"^\d{11}$", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        private readonly static Regex POSTAL_CODE_REGEX = new Regex(@"^\d{2}\-\d{3}$", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        private VideoRentalShopController _controller = VideoRentalShopController.Instance;
        private Client _selectedItem = null;


        public EditPanel()
        {
            InitializeComponent();
        }


        private void txtAddressPostalCode_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (e.Changes.First().AddedLength >= 1)
            {
                if (txtAddressPostalCode.Text.Length == 2)
                {
                    txtAddressPostalCode.AppendText("-");
                    txtAddressPostalCode.CaretIndex = txtAddressPostalCode.Text.Length;
                }
                if (txtAddressPostalCode.CaretIndex == 4 && txtAddressPostalCode.Text[3] == '-')
                {
                    if (txtAddressPostalCode.Text.Length > 4)
                    {
                        txtAddressPostalCode.Text = txtAddressPostalCode.Text.Substring(0, 3) + txtAddressPostalCode.Text.Substring(4, txtAddressPostalCode.Text.Length - 4);
                    }
                    else
                    {
                        txtAddressPostalCode.Text = txtAddressPostalCode.Text.Substring(0, txtAddressPostalCode.Text.Length - 1);
                    }
                    txtAddressPostalCode.CaretIndex = txtAddressPostalCode.Text.Length;
                }
                if (txtAddressPostalCode.Text.Length > 2 && txtAddressPostalCode.Text[2] != '-')
                {
                    txtAddressPostalCode.Text = txtAddressPostalCode.Text.Substring(0, 2) + "-" + txtAddressPostalCode.Text.Substring(2, txtAddressPostalCode.Text.Length - 2);
                    if (txtAddressPostalCode.Text.Length > 6)
                    {
                        txtAddressPostalCode.Text = txtAddressPostalCode.Text.Substring(0, txtAddressPostalCode.Text.Length - 1);
                    }
                    txtAddressPostalCode.CaretIndex = txtAddressPostalCode.Text.Length;
                }
            }
        }


        private void Clear()
        {
            txtName.Text = string.Empty;
            txtLastName.Text = string.Empty;
            txtPesel.Text = string.Empty;
            txtEmail.Text = string.Empty;
            txtAddressStreet.Text = string.Empty;
            txtAddressPostalCode.Text = string.Empty;
            txtAddressCity.Text = string.Empty;
            chbBlocked.IsChecked = false;
        }

        public void LoadItem(Client item)
        {
            _selectedItem = item;
            if (item == null)
            {
                Clear();
            }
            else
            {
                txtName.Text = item.Name ?? string.Empty;
                txtLastName.Text = item.LastName ?? string.Empty;
                txtPesel.Text = item.Pesel ?? string.Empty;
                txtEmail.Text = item.Email ?? string.Empty;
                txtAddressStreet.Text = item.Street ?? string.Empty;
                txtAddressPostalCode.Text = item.PostalCode ?? string.Empty;
                txtAddressCity.Text = item.City ?? string.Empty;
                chbBlocked.IsChecked = item.Blocked;
            }
        }

        public bool Add()
        {
            var completed = false;
            var item = new Client();
            if (CopyData(item))
            {
                completed = _controller.Data.Client.Add(item);

                if (completed)
                {
                    _controller.ShowMessage("Pomyślnie dodano klienta.", "Powodzenie", MessageType.Error);
                }
                else
                {
                    _controller.ShowMessage("Podczas dodawania danych o kliencie wystąpił błąd.\nSprawdź, czy wszystkie dane zostały podane i są poprawne.", "Błąd", MessageType.Error);
                }
            }

            return completed;
        }

        public bool Edit()
        {
            var completed = false;
            if (CopyData(_selectedItem, true))
            {
                completed = _controller.Data.Client.Edit(_selectedItem);

                if (completed)
                {
                    _controller.ShowMessage("Pomyślnie zmodyfikowano dane o kliencie.", "Powodzenie", MessageType.Error);
                }
                else
                {
                    _controller.ShowMessage("Podczas edycji danych o kliencie wystąpił błąd.\nSprawdź, czy wszystkie dane zostały podane i są poprawne.", "Błąd", MessageType.Error);
                }
            }

            return completed;
        }

        private bool CopyData(Client item, bool hasData = false)
        {
            var copy = (Client)null;
            if (hasData)
            {
                copy = new Client();
                CopyItem(copy, item);
            }

            item.Name = txtName.Text.Trim();
            item.LastName = txtLastName.Text.Trim();
            item.Pesel = txtPesel.Text.Trim();
            item.Email = txtEmail.Text.Trim();
            item.Street = txtAddressStreet.Text.Trim();
            item.PostalCode = txtAddressPostalCode.Text.Trim();
            item.City = txtAddressCity.Text.Trim();
            item.Blocked = chbBlocked.IsChecked == true;

            var valid = CheckData(item);
            if (valid)
            {
                valid = _controller.Data.Client.IsValid(item);
            }

            if (hasData && !valid)
            {
                CopyItem(item, copy);
            }

            return valid;
        }

        private void CopyItem(Client to, Client from)
        {
            to.Name = from.Name;
            to.LastName = from.LastName;
            to.Pesel = from.Pesel;
            to.Email = from.Email;
            to.Street = from.Street;
            to.PostalCode = from.PostalCode;
            to.City = from.City;
            to.Blocked = from.Blocked;
        }

        private bool CheckData(Client client)
        {
            if (string.IsNullOrWhiteSpace(client.Name) || string.IsNullOrWhiteSpace(client.LastName))
            {
                _controller.ShowMessage("Wymagane jest podanie imienia i nazwiska klienta (max 30 znaków).", "Uzupełnij dane", MessageType.Error);
                return false;
            }
            if (client.Name.Length > 30 || client.LastName.Length > 30)
            {
                _controller.ShowMessage("Maksymalna długość imienia i nazwiska to 30 znaków.", "Popraw dane", MessageType.Error);
                return false;
            }
            if (string.IsNullOrWhiteSpace(client.Pesel))
            {
                _controller.ShowMessage("Wymagane jest podanie numeru PESEL klienta.", "Uzupełnij dane", MessageType.Error);
                return false;
            }
            if (!PESEL_REGEX.IsMatch(client.Pesel))
            {
                _controller.ShowMessage("Podany numer PESEL klienta jest niepoprawny.", "Popraw dane", MessageType.Error);
                return false;
            }
            if (string.IsNullOrWhiteSpace(client.Street) || string.IsNullOrWhiteSpace(client.PostalCode) || string.IsNullOrWhiteSpace(client.City))
            {
                _controller.ShowMessage("Wymagane jest podanie pełnego adresu klienta.", "Uzupełnij dane", MessageType.Error);
                return false;
            }
            if (!POSTAL_CODE_REGEX.IsMatch(client.PostalCode))
            {
                _controller.ShowMessage("Podany kod pocztowy jest niepoprawny.", "Popraw dane", MessageType.Error);
                return false;
            }
            if (client.City.Length > 30 || client.Street.Length > 30)
            {
                _controller.ShowMessage("Podana ulica i/lub miejscowość są zbyt długie (max 30 znaków).", "Popraw dane", MessageType.Error);
                return false;
            }
            if (string.IsNullOrWhiteSpace(client.Name) || string.IsNullOrWhiteSpace(client.LastName))
            {
                _controller.ShowMessage("Wymagane jest podanie imienia i nazwiska klienta.", "Uzupełnij dane", MessageType.Error);
                return false;
            }
            if (!string.IsNullOrWhiteSpace(client.Email) && !EMAIL_REGEX.IsMatch(client.Email))
            {
                _controller.ShowMessage("Podany adres email jest niepoprawny.", "Popraw dane", MessageType.Error);
                return false;
            }

            return true;
        }
    }
}
